<template>
  <div class="subContainer">
    <div style="height: 8%;width: 100%;">
      <crumb ref="crumbRef" @goMenu="goMenu" @closeMenu="closeMenu"></crumb>
    </div>
    <div
      v-for="tab in tabsList"
      :key="tab.appName"
      :id="`subapp-container-${tab.appName}`"
      :style="{ display: tab.appName === activeTab?.topAppCode ? 'block' : 'none' }"
      class="container">
    </div>
  </div>
</template>
<script setup lang='ts'>
  import crumb from '../components/crumb.vue'
  import { start,loadMicroApp,initGlobalState,MicroAppStateActions } from 'qiankun';
  import apps from '../mirco/app'
  import { onMounted,ref,nextTick, getCurrentInstance } from 'vue';
  let {proxy}:any = getCurrentInstance()
  function goMenu(item:any){
    openTab(item)
  }
  function closeMenu(item:any,beforeMenuItem:any){
    closeTab(item,beforeMenuItem)
  }

  // 加载qiankun
  onMounted(()=>{
    // registerMicroApps(apps)
    start({
      sandbox: { experimentalStyleIsolation: true}, // 样式隔离
      prefetch: false, // 必须关闭预加载
      singular: false
    })
  })
  // 所有点击过的子应用列表
  let tabsList = ref<any>([])
  // 当前激活的子应用
  let activeTab = ref<any>(null)
  // 子应用实例
  const microAppInstances: Record<string, any> = {}

  const actions: MicroAppStateActions = initGlobalState();
  async function openTab(item: any) {
    console.log(tabsList.value,'tabList')
    // 1. tab 列表维护
    if (!tabsList.value.find((tab:any) => tab.key === item.sKey)) {
      tabsList.value.push({
        key: item.sKey,
        appName: item.topAppCode,
        path: item.path,
        bClosed:false, // 是否关闭过
      })
      // 只有在新增 tab 时才需要 nextTick 等待 DOM 渲染
      await nextTick() // 确保容器已渲染

      // 2. 检查同名子应用实例，已存在则先卸载
      const appName = item.topAppCode
      // 3. 检查 container dom 是否存在
      const containerDom = document.querySelector(`#subapp-container-${appName}`)
      if (!containerDom) {
        console.error('container dom 不存在！', `#subapp-container-${appName}`)
        return
      }
      // 3. 加载子应用
      const appConfig = apps.find((app:any) => app.name === appName)
      if (!appConfig) {
        console.error('未找到对应的子应用配置:', appName)
        return
      }
      // 只有在第一次打开tab时，才需要重新加载子应用
      //@ts-ignore
      // 一个自应用只加载一次实例
      console.log(microAppInstances[appName],'microAppInstances[appName]',appName)
      if(!microAppInstances[appName]){
        microAppInstances[appName] = loadMicroApp({
          ...appConfig,
          name:appConfig.name,
          container: `#subapp-container-${appName}`,
          props: {
            props: appConfig.props,
            path: item.path,
            qkTabKey: appName,
          }
        })
      }else{
        actions.setGlobalState({app:appName,route:item.path})
      }
      activeTab.value = item
    }else{
      // 如果是关闭过，但是没有卸载，那么就需要重新刷新一下
      let currentContainer = tabsList.value.find((tab:any) => tab.key === item.sKey)
      console.log('是关闭过的',currentContainer)
      if(currentContainer.bClosed){
        console.log('刷新了')
        refresh(item)
        currentContainer.bClosed = false
      }
      // 4. 切换显示
      activeTab.value = item
    }
  }
  // 3. 修改 refresh 函数
  function refresh(item?:any) {
    nextTick(()=>{
      let refreshItem = item??activeTab.value
      const event = new CustomEvent('mainRefresh', {
        detail: {path:refreshItem.path,appKey:refreshItem.topAppCode}
      });
      window.dispatchEvent(event);
    })
  }
  // 获取所有子应用name
  let allAppName = apps.map((app:any) => app.name)
  console.log(allAppName,'allAppName')

  // 关闭tab
  async function closeTab(item: any,reMountItem?:any) {
    // 怀疑是qiankun的bug，当多实例情况下，unmount可能会误删其他实例的dom，所以这里尝试不卸载，只隐藏
    // 如果所有的子应用都关闭了，那么再统一全部卸载

    // 当前tab栏中存在的子应用名称去重处理 [oma,mdm,auth]
    let crumbList = proxy.$refs.crumbRef.showMenuList
    let tabPiniaAppNames = Array.from(new Set(crumbList.map((mItem:any) => mItem.topAppCode)))
    let bAllClose = true // 是否全部关闭了：true全部关闭，false没有全部关闭
    // 如果当前点击的这个item的name存在于tabPiniaAppNames里面，说明没有删除完全
    let currentAppName = item.topAppCode // 当前点击的页面的子应用名称
    if(tabPiniaAppNames.indexOf(currentAppName) != -1){
      bAllClose = false
    }
    console.log(tabPiniaAppNames,currentAppName,'判断')
    console.log(bAllClose,'bAllColose')
    if(bAllClose){
      // 如果所有的子应用都关闭了，那么再统一全部卸载
      for (const tab of tabsList.value) {
        if (microAppInstances[tab.appName] && tab.appName == currentAppName) {
          await microAppInstances[tab.appName].unmount()
          delete microAppInstances[tab.appName]
        }
      }
      tabsList.value = tabsList.value.filter((tab:any) => tab.appName !== currentAppName)
      activeTab.value = reMountItem
    }else{
      // 如果要打开其他的tab，则重新显示(这里不会去挂载，只会走隐藏)
      if (reMountItem) {
        activeTab.value = reMountItem
      }
      const idx = tabsList.value.findIndex((tab: any) => tab.key === item.sKey)
      tabsList.value[idx].bClosed = true // 代表关闭过，关闭过重新打开需要刷新
    }
  }

</script>

<style scoped>
  .subContainer{
    width: 100%;
    height: 100%;
    color: var(--textColor);
  }
  .container{
    width: 90%;
    height: 90%;
    border: 1px solid #000;
  }

</style>
